package labox.innovation.gameserver.ai;

import static labox.innovation.gameserver.ai.CtrlIntention.AI_INTENTION_ACTIVE;
import static labox.innovation.gameserver.ai.CtrlIntention.AI_INTENTION_ATTACK;
import static labox.innovation.gameserver.ai.CtrlIntention.AI_INTENTION_CAST;
import static labox.innovation.gameserver.ai.CtrlIntention.AI_INTENTION_FOLLOW;
import static labox.innovation.gameserver.ai.CtrlIntention.AI_INTENTION_IDLE;
import static labox.innovation.gameserver.ai.CtrlIntention.AI_INTENTION_INTERACT;
import static labox.innovation.gameserver.ai.CtrlIntention.AI_INTENTION_MOVE_TO;
import static labox.innovation.gameserver.ai.CtrlIntention.AI_INTENTION_PICK_UP;

import java.util.List;

import javolution.util.FastList;
import labox.innovation.gameserver.model.L2CharPosition;
import labox.innovation.gameserver.model.L2ItemInstance;
import labox.innovation.gameserver.model.L2Object;
import labox.innovation.gameserver.model.L2Skill;
import labox.innovation.gameserver.model.L2ItemInstance.ItemLocation;
import labox.innovation.gameserver.model.actor.L2Character;
import labox.innovation.gameserver.model.actor.L2Summon;
import labox.innovation.gameserver.network.serverpackets.ActionFailed;
import labox.innovation.gameserver.templates.chars.NpcTemplate;
import labox.innovation.gameserver.templates.chars.NpcTemplate.AIType;
import labox.innovation.gameserver.util.Util;

/**
 * 此类管理了所有角色的AI基础逻辑.<BR>
 * <BR>
 * 
 * L2CharacterAI :<BR>
 * <BR>
 * <li>L2AttackableAI</li> <li>L2DoorAI</li> <li>L2PlayerAI</li> <li>L2SummonAI</li><BR>
 * <BR>
 * 
 */
public class L2CharacterAI extends AbstractAI {

	/**
	 * 保存一个完整的意图数据
	 * 
	 * @author Administrator
	 * 
	 */
	public class IntentionCommand {

		public CtrlIntention _crtlIntention;

		public Object _arg0, _arg1;

		protected IntentionCommand(CtrlIntention pIntention, Object pArg0, Object pArg1) {
			_crtlIntention = pIntention;
			_arg0 = pArg0;
			_arg1 = pArg1;
		}
	}

	/**
	 * L2CharacterAI的构造函数.<BR>
	 * <BR>
	 * 
	 * @param accessor
	 *            The AI accessor of the L2Character
	 * 
	 */
	public L2CharacterAI(L2Character.AIAccessor accessor) {
		super(accessor);
	}

	/**
	 * 获取下一个意图指令
	 * 
	 * @return
	 */
	public IntentionCommand getNextIntention() {
		return null;
	}

	@Override
	protected void onEvtAttacked(L2Character attacker) {
	}

	/**
	 * 管理空闲意图：停止攻击，移动，站立.<BR>
	 * <BR>
	 * 
	 * <B><U> Actions</U> :</B><BR>
	 * <BR>
	 * <li>Set the AI Intention to AI_INTENTION_IDLE</li> <li>Init cast and attack target</li> <li>Stop the actor auto-attack client side by sending Server->Client packet AutoAttackStop (broadcast)</li> <li>Stop the actor movement server side AND client side by sending Server->Client packet StopMove/StopRotation (broadcast)</li> <li>Stand up the actor server side AND client side by sending Server->Client packet ChangeWaitType (broadcast)</li><BR>
	 * <BR>
	 * 
	 */
	@Override
	protected void onIntentionIdle() {
		// Set the AI Intention to AI_INTENTION_IDLE
		changeIntention(AI_INTENTION_IDLE, null, null);
		// Init cast and attack target
		setCastTarget(null);
		setAttackTarget(null);
		// Stop the actor auto-attack client side by sending Server->Client packet AutoAttackStop (broadcast)
		clientStopAutoAttack();
	}

	/**
	 * 管理警戒意图状态:停止攻击，移动，并且调用思考事件.<BR>
	 * <BR>
	 * 
	 * <B><U> Actions</U> : <I>if the Intention is not already Active</I></B><BR>
	 * <BR>
	 * <li>Set the AI Intention to AI_INTENTION_ACTIVE</li> <li>Init cast and attack target</li> <li>Stop the actor auto-attack client side by sending Server->Client packet AutoAttackStop (broadcast)</li> <li>Stop the actor movement server side AND client side by sending Server->Client packet StopMove/StopRotation (broadcast)</li> <li>Launch the Think Event</li><BR>
	 * <BR>
	 * 
	 */
	@Override
	protected void onIntentionActive() {
		// 检查如果意图不是警戒状态，设置警戒状态
		if (getIntention() == AI_INTENTION_ACTIVE)
			return;
		// Set the AI Intention to AI_INTENTION_ACTIVE
		changeIntention(AI_INTENTION_ACTIVE, null, null);
		// Init cast and attack target
		setCastTarget(null);
		setAttackTarget(null);
		// Stop the actor auto-attack client side by sending Server->Client packet AutoAttackStop (broadcast)
		clientStopAutoAttack();
	}

	/**
	 * 管理攻击的意图：如果有必要停止当前的攻击，开始一个新的攻击，并触发思考事件<BR>
	 * <BR>
	 * 
	 * <B><U> Actions</U> : </B><BR>
	 * <BR>
	 * <li>Stop the actor auto-attack client side by sending Server->Client packet AutoAttackStop (broadcast)</li> <li>Set the Intention of this AI to AI_INTENTION_ATTACK</li> <li>Set or change the AI attack target</li> <li>Start the actor Auto Attack client side by sending Server->Client packet AutoAttackStart (broadcast)</li> <li>Launch the Think Event</li><BR>
	 * <BR>
	 * 
	 * 
	 * <B><U> Overridden in</U> :</B><BR>
	 * <BR>
	 * <li>L2AttackableAI : Calculate attack timeout</li><BR>
	 * <BR>
	 * 
	 */
	@Override
	protected void onIntentionAttack(L2Character target) {
		// 如果无敌状态存在，停止无敌状态
		if (_actor.getInvulEffect() != null)
			_actor.getInvulEffect().exit();

		//如果目标是空，取消Action
		if (target == null)
			return;

		//如果目标无敌则失败
		if (target.isInvul()) {
			_actor.sendPacket(ActionFailed.STATIC_PACKET);
			return;
		}

		//如果所有的技能都被禁止了，或者角色处于恐惧状态,取消
		if (_actor.isAllSkillsDisabled() || _actor.isAfraid()) {
			// Cancel action client side by sending Server->Client packet ActionFailed to the L2PcInstance actor
			return;
		}

		//检查如果意图不是攻击状态
		if (getIntention() != AI_INTENTION_ATTACK) {
			//改变成攻击状态
			changeIntention(AI_INTENTION_ATTACK, target, null);
			//通知客户端进入自动攻击状态
		}
		//通知客户端进入自动攻击状态
		clientStartAutoAttack(target);
	}

	/**
	 * 管理施法的意图：停止当前的攻击，初始化AI施法和通知思考事件.<BR>
	 * <BR>
	 * 
	 * <B><U> Actions</U> : </B><BR>
	 * <BR>
	 * <li>Set the AI cast target</li> <li>Stop the actor auto-attack client side by sending Server->Client packet AutoAttackStop (broadcast)</li> <li>Cancel action client side by sending Server->Client packet ActionFailed to the L2PcInstance actor</li> <li>Set the AI skill used by INTENTION_CAST</li> <li>Set the Intention of this AI to AI_INTENTION_CAST</li> <li>Launch the Think Event</li><BR>
	 * <BR>
	 * 
	 */
	@Override
	protected void onIntentionCast(L2Skill skill, L2Object target) {
		if(target==null)
			Thread.dumpStack();
		
		//如果无敌状态存在，停止无敌状态
		if (_actor.getInvulEffect() != null)
			_actor.getInvulEffect().exit();

		//如果目标无敌则失败
		if (target instanceof L2Character) {
			if (((L2Character) target).isInvul()) {
				_actor.sendPacket(ActionFailed.STATIC_PACKET);
				return;
			}
		}

		// Set the AI cast target
		setCastTarget((L2Character) target);
		// Set the AI skill used by INTENTION_CAST
		_skill = skill;
		// Change the Intention of this AbstractAI to AI_INTENTION_CAST
		changeIntention(AI_INTENTION_CAST, skill, target);
	}

	/**
	 * 管理移动的意图:停止当前的攻击，启动移动任务.<BR>
	 * <BR>
	 * 
	 * <B><U> Actions</U> : </B><BR>
	 * <BR>
	 * <li>Stop the actor auto-attack server side AND client side by sending Server->Client packet AutoAttackStop (broadcast)</li> <li>Set the Intention of this AI to AI_INTENTION_MOVE_TO</li> <li>Move the actor to Location (x,y,z) server side AND client side by sending Server->Client packet CharMoveToLocation (broadcast)</li><BR>
	 * <BR>
	 * 
	 */
	@Override
	protected void onIntentionMoveTo(L2CharPosition pos) {
		// Set the Intention of this AbstractAI to AI_INTENTION_MOVE_TO
		changeIntention(AI_INTENTION_MOVE_TO, pos, null);
		// 停止客户端的角色自动攻击状态，广播
		clientStopAutoAttack();
		// Move the actor to Location (x,y) server side AND client side by sending Server->Client packet CharMoveToLocation (broadcast)
		moveTo(pos.x, pos.y);
	}

	/**
	 * 管理跟随意图:停止当前的攻击，并且启动跟随任务.<BR>
	 * <BR>
	 * 
	 * <B><U> Actions</U> : </B><BR>
	 * <BR>
	 * <li>Stop the actor auto-attack server side AND client side by sending Server->Client packet AutoAttackStop (broadcast)</li> <li>Set the Intention of this AI to AI_INTENTION_FOLLOW</li> <li>Create and Launch an AI Follow Task to execute every 1s</li><BR>
	 * <BR>
	 * 
	 */
	@Override
	protected void onIntentionFollow(L2Character target, Integer offset) {
		if (_actor.isAllSkillsDisabled()) {
			return;
		}
		//定身和盘绕不能跟随
		if (_actor.isImmobilized() || _actor.isRooted()) {
			// Cancel action client side by sending Server->Client packet ActionFailed to the L2PcInstance actor
			return;
		}
		// 死亡时不能跟随
		if (_actor.isDead()) {
			return;
		}
		// 不能跟随自己
		if (_actor == target) {
			return;
		}

		// Set the Intention of this AbstractAI to AI_INTENTION_FOLLOW
		changeIntention(AI_INTENTION_FOLLOW, target, offset);
		moveToPawn(target, offset);
	}

	/**
	 * 管理拾取意图 : 设置拾取目标，启动移动到物件的任务 (offset=20).<BR>
	 * <BR>
	 * 
	 * <B><U> Actions</U> : </B><BR>
	 * <BR>
	 * <li>Set the AI pick up target</li> <li>Set the Intention of this AI to AI_INTENTION_PICK_UP</li> <li>Move the actor to Pawn server side AND client side by sending Server->Client packet MoveToPawn (broadcast)</li><BR>
	 * <BR>
	 * 
	 */
	@Override
	protected void onIntentionPickUp(L2Object object) {
		if (_actor.isAllSkillsDisabled()) {
			return;
		}
		// 停止客户端的自动攻击状态（广播）
		clientStopAutoAttack();
		//道具必须是没有在任何容器中的，即道具的位置是无效的
		if (object instanceof L2ItemInstance && ((L2ItemInstance) object).getLocation() != ItemLocation.VOID)
			return;
		// Set the Intention of this AbstractAI to AI_INTENTION_PICK_UP
		changeIntention(AI_INTENTION_PICK_UP, object, Integer.valueOf(10));
		// Set the AI pick up target
		setTarget(object);
	}

	/**
	 * 管理互动意图：设置交互的目标并且启动移动到角色的任务(offset=40).<BR>
	 * <BR>
	 * 
	 * <B><U> Actions</U> : </B><BR>
	 * <BR>
	 * <li>Stop the actor auto-attack client side by sending Server->Client packet AutoAttackStop (broadcast)</li> <li>Set the AI interact target</li> <li>Set the Intention of this AI to AI_INTENTION_INTERACT</li> <li>Move the actor to Pawn server side AND client side by sending Server->Client packet MoveToPawn (broadcast)</li><BR>
	 * <BR>
	 * 
	 */
	@Override
	protected void onIntentionInteract(L2Object object) {
		if (_actor.isAllSkillsDisabled()) {
			// Cancel action client side by sending Server->Client packet ActionFailed to the L2PcInstance actor
			return;
		}

		//  停止客户端的自动攻击状态（广播）
		clientStopAutoAttack();

		if (getIntention() != AI_INTENTION_INTERACT) {
			// Set the Intention of this AbstractAI to AI_INTENTION_INTERACT
			changeIntention(AI_INTENTION_INTERACT, object, Integer.valueOf(40));
			// Set the AI interact target
			setTarget(object);
			onEvtThink();
		}
	}

	/**
	 * 由子类实现其他部分.<BR>
	 * <BR>
	 */
	@Override
	protected void onEvtThink() {
		try {
			switch (_intention) {
			case AI_INTENTION_MOVE_TO:
				thinkMove();
				break;
			case AI_INTENTION_FOLLOW:
				thinkFollow();
				break;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	protected void thinkMove() {
		try {
			if (_actor.isMovementDisabled())
				return;
			if (_actor.updatePosition()) {
				if (_actor.moveToNextRoutePoint()) {
					notifyEvent(CtrlEvent.EVT_ARRIVED_REVALIDATE, null);
				} else {
					notifyEvent(CtrlEvent.EVT_ARRIVED, null);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	protected void thinkFollow() {
		L2Character followTarget = (L2Character) _intentionArg0;
		if (followTarget == null) {
			if (_actor instanceof L2Summon)
				((L2Summon) _actor).setFollowStatus(false);
			else
				setIntention(AI_INTENTION_IDLE);
			return;
		}

		int dis = Util.FastDistance2D(_actor.getX(), _actor.getY(), followTarget.getX(), followTarget.getY());

		int _range = 0;
		if (_intentionArg1 != null)
			_range = (Integer) _intentionArg1;

		if (dis > _range) {//如果不在角色的跟随范围内就查找角色的路径
			if (dis > 200) {//太远就放弃跟随
				if (_actor instanceof L2Summon)
					((L2Summon) _actor).setFollowStatus(false);
				else
					setIntention(AI_INTENTION_IDLE);
				return;
			}
			if (_actor.isMovementDisabled())
				return;

			if (_actor.updatePosition()) {
				if (_actor.moveToNextRoutePoint()) {
					notifyEvent(CtrlEvent.EVT_ARRIVED_REVALIDATE, null);
				} else {
					moveToPawn(followTarget, _range);
				}
			}
		} else {
			setIntention(AI_INTENTION_ACTIVE);
		}

	}

	/**
	 * 由子类实现.<BR>
	 * <BR>
	 */
	@Override
	protected void onEvtAggression(L2Character target, int aggro) {
		// do nothing
	}

	/**
	 * 眩晕事件的处理.<BR>
	 * <BR>
	 * 
	 * <B><U> Actions</U> :</B><BR>
	 * <BR>
	 * <li>Stop the actor auto-attack client side by sending Server->Client packet AutoAttackStop (broadcast)</li> <li>Stop the actor movement server side AND client side by sending Server->Client packet StopMove/StopRotation (broadcast)</li> <li>Break an attack and send Server->Client ActionFailed packet and a System Message to the L2Character</li> <li>Break a cast and send Server->Client ActionFailed packet and a System Message to the L2Character</li> <li>Launch actions corresponding to the Event onAttacked (only for L2AttackableAI after the stunning periode)</li><BR>
	 * <BR>
	 * 
	 */
	@Override
	protected void onEvtStunned(L2Character attacker) {
		// 停止客户端的自动战斗状态 (广播)
		clientStopAutoAttack();
		// 通知被攻击的事件（仅仅是为L2AttackableAI的眩晕状态结束时设计的）
		onEvtAttacked(attacker);
	}

	/**
	 * 瘫痪事件的处理
	 */
	@Override
	protected void onEvtParalyzed(L2Character attacker) {
		//停止客户端的自动战斗状态 (广播)
		clientStopAutoAttack();

		//通知被攻击的事件（仅仅是为L2AttackableAI的瘫痪状态结束时设计的）
		onEvtAttacked(attacker);
	}

	/**
	 * 睡眠事件的处理.<BR>
	 * <BR>
	 * 
	 * <B><U> Actions</U> :</B><BR>
	 * <BR>
	 * <li>Stop the actor auto-attack client side by sending Server->Client packet AutoAttackStop (broadcast)</li> <li>Stop the actor movement server side AND client side by sending Server->Client packet StopMove/StopRotation (broadcast)</li> <li>Break an attack and send Server->Client ActionFailed packet and a System Message to the L2Character</li> <li>Break a cast and send Server->Client ActionFailed packet and a System Message to the L2Character</li><BR>
	 * <BR>
	 * 
	 */
	@Override
	protected void onEvtSleeping(L2Character attacker) {
		//停止客户端的自动战斗状态 (广播)
		clientStopAutoAttack();
	}

	/**
	 * 盘绕事件的处理.<BR>
	 * <BR>
	 * 
	 * <B><U> Actions</U> :</B><BR>
	 * <BR>
	 * <li>Stop the actor movement server side AND client side by sending Server->Client packet StopMove/StopRotation (broadcast)</li> <li>Launch actions corresponding to the Event onAttacked</li><BR>
	 * <BR>
	 * 
	 */
	@Override
	protected void onEvtRooted(L2Character attacker) {
		// Launch actions corresponding to the Event onAttacked
		onEvtAttacked(attacker);
	}

	/**
	 * 混乱事件的处理.<BR>
	 * <BR>
	 * 
	 * <B><U> Actions</U> :</B><BR>
	 * <BR>
	 * <li>Stop the actor movement server side AND client side by sending Server->Client packet StopMove/StopRotation (broadcast)</li> <li>Launch actions corresponding to the Event onAttacked</li><BR>
	 * <BR>
	 * 
	 */
	@Override
	protected void onEvtConfused(L2Character attacker) {
		// Launch actions corresponding to the Event onAttacked
		onEvtAttacked(attacker);
	}

	/**
	 * 禁言事件的处理.<BR>
	 * <BR>
	 * 
	 * <B><U> Actions</U> :</B><BR>
	 * <BR>
	 * <li>Break a cast and send Server->Client ActionFailed packet and a System Message to the L2Character</li><BR>
	 * <BR>
	 * 
	 */
	@Override
	protected void onEvtMuted(L2Character attacker) {
		// Break a cast and send Server->Client ActionFailed packet and a System Message to the L2Character
		onEvtAttacked(attacker);
	}

	/**
	 * 警戒事件的处理.<BR>
	 * <BR>
	 * 
	 * <B><U> Actions</U> :</B><BR>
	 * <BR>
	 * <li>Launch actions corresponding to the Event Think</li><BR>
	 * <BR>
	 * 
	 */
	@Override
	protected void onEvtReadyToAct() {
		// Launch actions corresponding to the Event Think
		onEvtThink();
	}

	/**
	 * 有子类完成.<BR>
	 * <BR>
	 */
	@Override
	protected void onEvtUserCmd(Object arg0, Object arg1) {
		// do nothing
	}

	/**
	 * 目的点到达事件的处理.<BR>
	 * <BR>
	 * 
	 * <B><U> Actions</U> :</B><BR>
	 * <BR>
	 * <li>If the Intention was AI_INTENTION_MOVE_TO, set the Intention to AI_INTENTION_ACTIVE</li> <li>Launch actions corresponding to the Event Think</li><BR>
	 * <BR>
	 * 
	 */
	@Override
	protected void onEvtArrived() {
		//检查进入的区域
		_accessor.getActor().revalidateZone(true);
		// 把移动的状态转成警戒状态
		setIntention(AI_INTENTION_ACTIVE);

	}

	/**
	 * 到达一个路由点的检查事件的处理.<BR>
	 * <BR>
	 * 
	 * <B><U> Actions</U> :</B><BR>
	 * <BR>
	 * <li>Launch actions corresponding to the Event Think</li><BR>
	 * <BR>
	 * 
	 */
	@Override
	protected void onEvtArrivedRevalidate() {
	}

	/**
	 * 忽略某个对象的事件处理.<BR>
	 * <BR>
	 * 
	 * <B><U> Actions</U> :</B><BR>
	 * <BR>
	 * <li>If the object was targeted and the Intention was AI_INTENTION_INTERACT or AI_INTENTION_PICK_UP, set the Intention to AI_INTENTION_ACTIVE</li> <li>If the object was targeted to attack, stop the auto-attack, cancel target and set the Intention to AI_INTENTION_ACTIVE</li> <li>If the object was targeted to cast, cancel target and set the Intention to AI_INTENTION_ACTIVE</li> <li>If the object was targeted to follow, stop the movement, cancel AI Follow Task and set the Intention to AI_INTENTION_ACTIVE</li> <li>If the targeted object was the actor , cancel AI target, stop AI Follow Task, stop the movement and set the Intention to AI_INTENTION_IDLE</li><BR>
	 * <BR>
	 * 
	 */
	@Override
	protected void onEvtForgetObject(L2Object object) {
		// If the object was targeted  and the Intention was AI_INTENTION_INTERACT or AI_INTENTION_PICK_UP, set the Intention to AI_INTENTION_ACTIVE
		if (getTarget() == object) {
			setTarget(null);
			if (getIntention() == AI_INTENTION_INTERACT)
				setIntention(AI_INTENTION_ACTIVE);
			else if (getIntention() == AI_INTENTION_PICK_UP)
				setIntention(AI_INTENTION_ACTIVE);
		}

		// Check if the object was targeted to attack
		if (getAttackTarget() == object) {
			// Cancel attack target
			setAttackTarget(null);
			// Set the Intention of this AbstractAI to AI_INTENTION_ACTIVE
			setIntention(AI_INTENTION_ACTIVE);
		}

		// Check if the object was targeted to cast
		if (getCastTarget() == object) {
			// Cancel cast target
			setCastTarget(null);
			// Set the Intention of this AbstractAI to AI_INTENTION_ACTIVE
			setIntention(AI_INTENTION_ACTIVE);
		}

		// Check if the object was targeted to follow
		if (getFollowTarget() == object) {
			// Set the Intention of this AbstractAI to AI_INTENTION_ACTIVE
			setIntention(AI_INTENTION_ACTIVE);
		}
	}

	/**
	 * 取消事件处理.<BR>
	 * <BR>
	 * 
	 * <B><U> Actions</U> :</B><BR>
	 * <BR>
	 * <li>Stop an AI Follow Task</li> <li>Launch actions corresponding to the Event Think</li><BR>
	 * <BR>
	 * 
	 */
	@Override
	protected void onEvtCancel() {
		clientStopAutoAttack();
		// Launch actions corresponding to the Event Think
		onEvtThink();
	}

	/**
	 * 死亡事件的处理.<BR>
	 * <BR>
	 * 
	 * <B><U> Actions</U> :</B><BR>
	 * <BR>
	 * <li>Stop an AI Follow Task</li> <li>Kill the actor client side by sending Server->Client packet AutoAttackStop, StopMove/StopRotation, Die (broadcast)</li><BR>
	 * <BR>
	 * 
	 */
	@Override
	protected void onEvtDead() {
		// Kill the actor client side by sending Server->Client packet AutoAttackStop, StopMove/StopRotation, Die (broadcast)
		clientNotifyDead();
	}

	/**
	 * 技能释放完成的事件处理.<BR>
	 * <BR>
	 */
	@Override
	protected void onEvtFinishCasting() {
		// do nothing
	}

	/**
	 * 修改目前的意图和行为，如果目标是丢失或死亡.<BR>
	 * <BR>
	 * 
	 * <B><U> Actions</U> : <I>If the target is lost or dead</I></B><BR>
	 * <BR>
	 * <li>Stop the actor auto-attack client side by sending Server->Client packet AutoAttackStop (broadcast)</li> <li>Stop the actor movement server side AND client side by sending Server->Client packet StopMove/StopRotation (broadcast)</li> <li>Set the Intention of this AbstractAI to AI_INTENTION_ACTIVE</li><BR>
	 * <BR>
	 * 
	 * <B><U> Example of use </U> :</B><BR>
	 * <BR>
	 * <li>L2PLayerAI, L2SummonAI</li><BR>
	 * <BR>
	 * 
	 * @param target
	 *            The targeted L2Object
	 * 
	 * @return True if the target is lost or dead (false if fakedeath)
	 * 
	 */
	protected boolean checkTargetLostOrDead(L2Character target) {
		if (target == null || target.isDead() || target.getScene() != _actor.getScene()) {
			return true;
		}
		return false;
	}

	/**
	 * 修改目前的意图和行为，如果目标是丢失.<BR>
	 * <BR>
	 * 
	 * <B><U> Actions</U> : <I>If the target is lost</I></B><BR>
	 * <BR>
	 * <li>Stop the actor auto-attack client side by sending Server->Client packet AutoAttackStop (broadcast)</li> <li>Stop the actor movement server side AND client side by sending Server->Client packet StopMove/StopRotation (broadcast)</li> <li>Set the Intention of this AbstractAI to AI_INTENTION_ACTIVE</li><BR>
	 * <BR>
	 * 
	 * <B><U> Example of use </U> :</B><BR>
	 * <BR>
	 * <li>L2PLayerAI, L2SummonAI</li><BR>
	 * <BR>
	 * 
	 * @param target
	 *            The targeted L2Object
	 * 
	 * @return True if the target is lost
	 * 
	 */
	protected boolean checkTargetLost(L2Object target) {
		if (target == null) {
			// Set the Intention of this AbstractAI to AI_INTENTION_ACTIVE
			setIntention(AI_INTENTION_ACTIVE);
			return true;
		}
		return false;
	}

	/**
	 * 自我分析处理类
	 * 
	 * @author Administrator
	 * 
	 */
	protected class SelfAnalysis {

		public List<L2Skill> generalSkills = new FastList<L2Skill>();

		public List<L2Skill> buffSkills = new FastList<L2Skill>();

		public List<L2Skill> debuffSkills = new FastList<L2Skill>();

		/**
		 * 最后一次加buf的时间
		 */
		public int lastBuffTick;

		/**
		 * 最后一次加debuf的时间
		 */
		public int lastDebuffTick;

		/**
		 * 是否有攻击魔法
		 */
		public boolean hasLongRangeSkills;

		public AIType aiType;

		public void init() {
			aiType = ((NpcTemplate) _actor.getTemplate())._aI;
			//技能分类分析
			for (L2Skill sk : _actor.getAllSkills()) {
				if (sk.isPassive())//被动技能忽略
					continue;
				switch (sk.getSkillType()) {
				case HEAL:
				case HEAL_PERCENT:
				case HEAL_STATIC:
				case BALANCE_LIFE:
				case HOT:
					buffSkills.add(sk);//收集恢复的技能
					continue; // 就不在考虑战斗的东西了 
				case BUFF:
					buffSkills.add(sk);//收集buff的技能
					continue; // 就不在考虑战斗的东西了 
				case STUN:
				case MUTE:
				case SLEEP:
				case ROOT:
				case FEAR:
				case CONFUSION:
				case DEBUFF:
				case CANCEL:
				case NEGATE:
					debuffSkills.add(sk);
					hasLongRangeSkills = true;
					break;
				case NOTDONE:
					continue; // 就不在考虑战斗的东西了 
				default:
					generalSkills.add(sk);
					hasLongRangeSkills = true;
					break;
				}
			}
		}
	}
}
